﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
using Cesave.DistributedServices.PermisosModule.WindowsHost.Resources;
using Cesave.Domain.Core.Entities;
using Cesave.Domain.PermisosModule.Contracts.Distritos;
using Cesave.Domain.PermisosModule.Contracts.Estados;
using Cesave.Domain.PermisosModule.Entities;
using Cesave.Infrastructure.CrossCutting.IoC;

namespace Cesave.DistributedServices.PermisosModule.WindowsHost.ViewModels.Catalogs.Distritos
{
	public partial class DistritosViewModel
	{
		#region Private properties

		/// <summary>
		/// 
		/// </summary>
		private List<Distrito> _distritos;

		/// <summary>
		/// 
		/// </summary>
		private List<Estado> _estadosDistrito;

		/// <summary>
		/// 
		/// </summary>
		private Distrito _distrito;

		/// <summary>
		/// 
		/// </summary>
		private Estado _estadoDistrito;

		#endregion

		#region Public properties

		/// <summary>
		/// 
		/// </summary>
		public List<Distrito> Distritos
		{
			get
			{
				return _distritos;
			}
			private set
			{
				_distritos = value;
				if (_distritos != null)
					RaisePropertyChanged("Distritos");
			}
		}

		/// <summary>
		/// 
		/// </summary>
		public List<Estado> EstadosDistrito
		{
			get
			{
				return _estadosDistrito;
			}
			private set
			{
				_estadosDistrito = value;
				if (_estadosDistrito != null)
					RaisePropertyChanged("EstadosDistrito");
			}
		}

		/// <summary>
		/// 
		/// </summary>
		public Distrito Distrito
		{
			get
			{
				return _distrito;
			}
			private set
			{
				_distrito = value;
				if (_distrito != null)
					RaisePropertyChanged("Distrito");
			}
		}

		/// <summary>
		/// 
		/// </summary>
		public Estado EstadoDistrito
		{
			get
			{
				return _estadoDistrito;
			}
			private set
			{
				_estadoDistrito = value;
				if (_estadoDistrito != null)
					RaisePropertyChanged("EstadoDistrito");
			}
		}

		/// <summary>
		/// 
		/// </summary>
		public bool IsDistritoReady
		{
			get
			{
				return Distrito != null;
			}
		}

		#endregion

		#region Actions

		/// <summary>
		/// 
		/// </summary>
		private void LoadDistritos()
		{
			StartWaiting();
			using (BackgroundWorker worker = new BackgroundWorker())
			{
				worker.DoWork += (sender, e) =>
				{
					IDistritoService distritoService = IoCFactory.Resolve<IDistritoService>();
					e.Result = distritoService.FindDistritosByEstado(Estado.EstadoGuid);
				};
				worker.RunWorkerCompleted += (sender, e) =>
				{
					EndWaiting();
					if (!e.Cancelled && e.Error == null)
						Distritos = e.Result as List<Distrito>;
					else if (e.Error != null)
						MessageBox.Show(
							_distritosView,
							e.Error.Message,
							WindowTitles.DistritosWindowTitle,
							MessageBoxButtons.OK,
							MessageBoxIcon.Error
						);
				};
				worker.WorkerSupportsCancellation = true;
				worker.RunWorkerAsync();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		private void LoadEstadosDistrito()
		{
			StartWaiting();
			using (BackgroundWorker worker = new BackgroundWorker())
			{
				worker.DoWork += (sender, e) =>
				{
					IEstadoService estadoService = IoCFactory.Resolve<IEstadoService>();
					e.Result = estadoService.FindAllEstados();
				};
				worker.RunWorkerCompleted += (sender, e) =>
				{
					EndWaiting();
					if (!e.Cancelled && e.Error == null)
						EstadosDistrito = e.Result as List<Estado>;
					else if (e.Error != null)
						MessageBox.Show(
							_distritosView,
							e.Error.Message,
							WindowTitles.DistritosWindowTitle,
							MessageBoxButtons.OK,
							MessageBoxIcon.Error
						);
				};
				worker.WorkerSupportsCancellation = true;
				worker.RunWorkerAsync();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void AddNewDistrito(object sender, EventArgs e)
		{
			_distritosView.distritosBindingSource.AddingNew += AddingNewDistrito;
			_distritosView.distritosBindingSource.AddNew();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void AddingNewDistrito(object sender, AddingNewEventArgs e)
		{
			Distrito distrito = new Distrito
			{
				DistritoGuid = Guid.NewGuid(),
				Domicilio = string.Empty,
				Email = string.Empty,
				EstadoId = Estado.EstadoId,
				EstadoGuid = Estado.EstadoGuid,
				Nombre = string.Empty,
				Numero = string.Empty,
				Status = true,
				Telefono = string.Empty,
			};
			distrito.MarkAsAdded();
			Distrito = distrito;
			e.NewObject = Distrito;
			FocusDefaultControl();
			AddNewDistritoPersonal(sender, new EventArgs());
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void SaveDistrito(object sender, EventArgs e)
		{
			if (_distritosView.validator.Validate().IsValid)
			{
				StartWaiting();
				using (BackgroundWorker worker = new BackgroundWorker())
				{
					worker.DoWork += (wSender, wArgs) =>
					{
						IDistritoService distritoService = IoCFactory.Resolve<IDistritoService>();
						if (Distrito.ChangeTracker.State == ObjectState.Added)
							distritoService.AddDistrito(Distrito);
						else if (Distrito.ChangeTracker.State == ObjectState.Modified)
							distritoService.ChangeDistrito(Distrito);
						Distrito.AcceptChanges();
					};
					worker.RunWorkerCompleted += (wSender, wArgs) =>
					{
						EndWaiting();
						if (!wArgs.Cancelled && wArgs.Error == null)
							SaveDistritoPersonal(sender, e);
						else if (wArgs.Error != null)
							MessageBox.Show(
								_distritosView,
								wArgs.Error.Message,
								WindowTitles.DistritosWindowTitle,
								MessageBoxButtons.OK,
								MessageBoxIcon.Error
							);
					};
					worker.WorkerSupportsCancellation = true;
					worker.RunWorkerAsync();
				}
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void DeleteDistrito(object sender, EventArgs e)
		{
			StartWaiting();
			using (BackgroundWorker worker = new BackgroundWorker())
			{
				worker.DoWork += (wSender, wArgs) =>
				{
					IDistritoService distritoService = IoCFactory.Resolve<IDistritoService>();
					Distrito.MarkAsDeleted();
					distritoService.DeleteDistrito(Distrito);
					Distrito.AcceptChanges();
				};
				worker.RunWorkerCompleted += (wSender, wArgs) =>
				{
					EndWaiting();
					if (!wArgs.Cancelled && wArgs.Error == null)
						DeleteDistritoPersonal(sender, e);
					else if (wArgs.Error != null)
						MessageBox.Show(
							_distritosView,
							wArgs.Error.Message,
							WindowTitles.DistritosWindowTitle,
							MessageBoxButtons.OK,
							MessageBoxIcon.Error
						);
				};
				worker.WorkerSupportsCancellation = true;
				worker.RunWorkerAsync();
			}
		}

		#endregion

		#region Event methods

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void SetCurrentDistrito(object sender, EventArgs e)
		{
			BindingSource bindingSource = sender as BindingSource;
			if (bindingSource != null)
				if (bindingSource.Current != null)
					Distrito = bindingSource.Current as Distrito;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void SetCurrentEstadoDistrito(object sender, EventArgs e)
		{
			BindingSource bindingSource = sender as BindingSource;
			if (bindingSource != null)
				if (bindingSource.Current != null)
					EstadoDistrito = bindingSource.Current as Estado;
		}

		/// <summary>
		/// 
		/// </summary>
		private void OnDistritosPropertyChanged()
		{
			_distritosView.distritosBindingSource.DataSource = Distritos;
			_distritosView.distritosBindingSource.CurrentChanged += SetCurrentDistrito;
			SetCurrentDistrito(_distritosView.distritosBindingSource, new EventArgs());
		}

		/// <summary>
		/// 
		/// </summary>
		private void OnDistritoPropertyChanged()
		{
			//if (!IsCicloReady)
			//{
			//    ICicloService cicloService = IoCFactory.Resolve<ICicloService>();
			//    Ciclo = cicloService.FindCicloActual();
			//}
			//IDistritoPersonalService distritoPersonalService = IoCFactory.Resolve<IDistritoPersonalService>();
			//DistritoPersonal = distritoPersonalService.FindDistritoPersonalByDistritoAndCiclo(Distrito.DistritoGuid, Ciclo.CicloGuid);
			LoadDistritoPersonal();
		}

		/// <summary>
		/// 
		/// </summary>
		private void OnEstadosDistritoPropertyChanged()
		{
			_distritosView.estadoBindingSource.DataSource = EstadosDistrito;
			_distritosView.estadoBindingSource.CurrentChanged += SetCurrentEstadoDistrito;
			SetCurrentEstadoDistrito(_distritosView.estadoBindingSource, new EventArgs());
		}

		/// <summary>
		/// 
		/// </summary>
		private void OnEstadoDistritoPropertyChanged()
		{
			if (IsDistritoReady)
			{
				Distrito.EstadoGuid = EstadoDistrito.EstadoGuid;
				Distrito.EstadoId = EstadoDistrito.EstadoId;
			}
		}

		#endregion
	}
}
